package com.conversationboard.logger;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class Statistics {

    private List<List<LogMessage>> buckets = Collections.synchronizedList(new ArrayList<List<LogMessage>>(Function.values().length));


    public Statistics() {

        /* Initialise */

        buckets.add(Function.BOARDS.getId(), Collections.synchronizedList(new LinkedList<LogMessage>()));
        buckets.add(Function.NEW_ANSWERS.getId(), Collections.synchronizedList(new LinkedList<LogMessage>()));
        buckets.add(Function.NEW_QUESTIONS.getId(), Collections.synchronizedList(new LinkedList<LogMessage>()));
        buckets.add(Function.RECENT_QUESTIONS.getId(), Collections.synchronizedList(new LinkedList<LogMessage>()));
        buckets.add(Function.SEARCHTHREADS.getId(), Collections.synchronizedList(new LinkedList<LogMessage>()));
        buckets.add(Function.SEARCHMESSAGES.getId(), Collections.synchronizedList(new LinkedList<LogMessage>()));
        buckets.add(Function.SEARCHUSER.getId(), Collections.synchronizedList(new LinkedList<LogMessage>()));
        buckets.add(Function.SEARCHDATE.getId(), Collections.synchronizedList(new LinkedList<LogMessage>()));
        buckets.add(Function.UNANSWERED_QUESTIONS.getId(), Collections.synchronizedList(new LinkedList<LogMessage>()));
        buckets.add(Function.THREAD.getId(), Collections.synchronizedList(new LinkedList<LogMessage>()));
        buckets.add(Function.ADD_QUESTION.getId(), Collections.synchronizedList(new LinkedList<LogMessage>()));
        buckets.add(Function.ADD_ANSWER.getId(), Collections.synchronizedList(new LinkedList<LogMessage>()));
    }


    public void putLogMessage(LogMessage logMessage) {
        List<LogMessage> bucket = buckets.get(logMessage.getFunction().getId());
        bucket.add(logMessage);
    }


    public long getMinimumQueryTime(Function function) {

        List<LogMessage> bucket = buckets.get(function.getId());

        long queryTime = 0;

        if (bucket.size() > 0) {
            queryTime = bucket.get(0).getQueryTimeInMilliseconds();
        } else {
            return 0;
        }

        for (LogMessage message : bucket) {
            if ((message.getQueryTimeInMilliseconds() < queryTime) && (queryTime != 0)) {
                queryTime = message.getQueryTimeInMilliseconds();
            }
        }

        return queryTime;

    }


    public long getAverageQueryTime(Function function) {

        List<LogMessage> bucket = buckets.get(function.getId());
        long queryTime = 0;

        for (LogMessage message : bucket) {
            queryTime += message.getQueryTimeInMilliseconds();
        }

        if (bucket.size() > 0) {
            return queryTime / bucket.size();
        } else {
            return 0;
        }
    }


    public long getMaximumQueryTime(Function function) {

        List<LogMessage> bucket = buckets.get(function.getId());
        long queryTime = 0;

        for (LogMessage message : bucket) {
            if (message.getQueryTimeInMilliseconds() > queryTime) {
                queryTime = message.getQueryTimeInMilliseconds();
            }
        }

        return queryTime;
    }


    public int getNumberOfTimesCalled(Function function) {

        List<LogMessage> bucket = buckets.get(function.getId());
        return bucket.size();

    }


    public int getCachedPercentage(Function function) {

        List<LogMessage> bucket = buckets.get(function.getId());
        int cachedCalls = 0;

        for (LogMessage message : bucket) {
            if (message.isGotFromCache()) {
                cachedCalls++;
            }
        }

        if (bucket.size() == 0) {
            return 0;
        } else {
            return (cachedCalls * 100) / bucket.size();
        }
    }

}
